package com.ac.dao.impl;

import java.io.Serializable;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ac.dao.HibernateBaseDao;
import com.ac.entity.pagination.Page;

public class HibernateBaseDaoImpl extends HibernateDaoSupport implements
		HibernateBaseDao {

	@SuppressWarnings("unchecked")
	public Page getPageBysql(final String sqlCount, final String sqlInfo,
			final List sqlCountParameters, final List sqlInfoParameters,
			int offset, final Class resultListClass) {
		Page page = new Page();
		int totalSize = this.getHibernateTemplate().execute(
				new HibernateCallback<Integer>() {

					public Integer doInHibernate(Session arg0)
							throws HibernateException, SQLException {

						Query queryCount = arg0.createSQLQuery(sqlCount);

						if (sqlCountParameters != null) {
							for (int i = 0; i < sqlCountParameters.size(); i++) {
								queryCount.setParameter(i, sqlCountParameters
										.get(i));
							}
						}
						int totalSize = ((BigInteger) queryCount.list().get(0))
								.intValue();

						return totalSize;
					}

				});
		page.setTotalSize(totalSize);
		page.setOffset(offset);

		final int firstResult = page.getOffset();
		final int maxResults = page.getPageSize();

		List list = this.getHibernateTemplate().execute(
				new HibernateCallback<List>() {
					public List doInHibernate(Session arg0)
							throws HibernateException, SQLException {
						Query queryInfo = null;
						if(resultListClass == null){
							queryInfo = arg0.createSQLQuery(sqlInfo);
						}else{
							queryInfo = arg0.createSQLQuery(sqlInfo)
									.setResultTransformer(
											Transformers
													.aliasToBean(resultListClass));
						}

						if (sqlInfoParameters != null) {
							for (int i = 0; i < sqlInfoParameters.size(); i++) {
								queryInfo.setParameter(i, sqlInfoParameters
										.get(i));
							}
						}
						queryInfo.setFirstResult(firstResult);
						queryInfo.setMaxResults(maxResults);

						return queryInfo.list();
					}

				});

		page.setList(list);

		return page;
	}

	@SuppressWarnings("unchecked")
	public Object getObject(Object o) {

		List list = this.getHibernateTemplate().findByExample(o);
		

		if (list != null && list.size() > 0) {
			return list.get(0);
		}

		return null;
	}
	
	@SuppressWarnings("unchecked")
	public Page getPageBySimpleHQL(final String hql,int offset) {
		Page page = new Page();
		int totalSize = this.getHibernateTemplate().execute(
				new HibernateCallback<Integer>() {

					public Integer doInHibernate(Session arg0)
							throws HibernateException, SQLException {

						Query queryCount = arg0.createQuery(hql);
						int totalSize = queryCount.list().size();
						return totalSize;
					}

				});
		page.setTotalSize(totalSize);
		page.setOffset(offset);

		final int firstResult = page.getOffset();
		final int maxResults = page.getPageSize();

		List list = this.getHibernateTemplate().execute(
				new HibernateCallback<List>() {
					public List doInHibernate(Session arg0)
							throws HibernateException, SQLException {
						Query queryInfo = arg0.createQuery(hql);
						queryInfo.setFirstResult(firstResult);
						queryInfo.setMaxResults(maxResults);

						return queryInfo.list();
					}

				});

		page.setList(list);

		return page;
	}
	
	public void saveOrUpdate(Object o){
		this.getHibernateTemplate().saveOrUpdate(o);
	}
	
	
	public void delete(Object o){
		this.getHibernateTemplate().delete(o);
	}

	@SuppressWarnings("unchecked")
	public Object getObjectByKey(Class c, Serializable id) {
		return this.getHibernateTemplate().get(c, id);
	}

	@SuppressWarnings("unchecked")
	public List getAllList(Class c) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().loadAll(c);
	}

	public Object getObject(final String sql, final Class resultListClass) {
		
		return this.getHibernateTemplate().execute(new HibernateCallback<Object>() {

			public Object doInHibernate(Session arg0)
					throws HibernateException, SQLException {
				List list =  arg0.createSQLQuery(sql).setResultTransformer(Transformers
						.aliasToBean(resultListClass)).list();
				if(list == null || list.size() < 1) return null;
				else return list.get(0);
			}
				
		});
		
	}
	public List getList(final String sql, final Class resultListClass) {
		return this.getHibernateTemplate().execute(new HibernateCallback<List>() {

			public List doInHibernate(Session arg0)
					throws HibernateException, SQLException {
				List list =  arg0.createSQLQuery(sql).setResultTransformer(Transformers
						.aliasToBean(resultListClass)).list();
				if(list == null || list.size() < 1) return new ArrayList();
				else return list;
			}
				
		});
	}

}
